﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using LogProjectManager;
using System.ComponentModel;
using System.Management;
using CommonExtenControl.Model;
using Newtonsoft.Json;
using System.IO;
using Microsoft.Win32;
using System.Threading;
using CommonExtenControl.Model.Base;
using System.Collections.Concurrent;
using Newtonsoft.Json.Linq;
using CommonExtenControl.Enum;
using System.Diagnostics;
using CustomControls.PoptipCtr;
using CommonExtenControl.Event;
using Prism.Events;
using CommonServiceLocator;

namespace CommonExtenControl
{
    public class ClientNetWorkControl
    {
        private IEventAggregator Event;
        //文件路径
        string recStr = null;
        string filePath = string.Empty;
        //文件名称
        string fileName = string.Empty;
        Socket socketclient = null;
        List<IPEndPoint> mlist = new List<IPEndPoint>();
        protected BackgroundWorker worker = new BackgroundWorker();

        private ConcurrentQueue<string> MesgList { set; get; }

        public ClientNetWorkControl() 
        {
            MesgList=new ConcurrentQueue<string>();
            Event = ServiceLocator.Current.GetInstance<IEventAggregator>();
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            
        }

        private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            int Sum = e.ProgressPercentage;
            Console.WriteLine(Sum);
            //if (e.ProgressPercentage == 0)
            //{
            //    pform.Percent = "00";
            //}
            //else
            //{
            //    pform.Percent = e.ProgressPercentage.ToString();
            //}
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            SendFile(this.filePath);
        }

      

        public  void ConnectToServer(string _ipdarress, string _port) 
        {
            try
            {
                socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress address = IPAddress.Parse(_ipdarress);
                IPEndPoint point = new IPEndPoint(address, int.Parse(_port));
                try
                {
                    socketclient.Connect(point);
                    IsHaveConnected = true;
                }
                catch (Exception ex)
                {
                                 
                }
                RunCheckSocketState(point);
                RunRecveMsg();
                RunHeartBeat();
            
                Thread threadclient = new Thread(recv);
                threadclient.IsBackground = true;
                threadclient.Start();

            }
            catch (Exception ex) 
            {
                
            }
        }



        private bool IsHaveConnected { set; get; }

        public void RunCheckSocketState(IPEndPoint point) 
        {
            Task.Run(async () => {
                while (true)
                {
                   
                    if (!socketclient.Connected)
                    {
                        if (IsHaveConnected)
                        {
                            IsHaveConnected = false;
                            socketclient.Close();
                            socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        }
                        try
                        {
                            socketclient.Connect(point);
                            IsHaveConnected = true;
                        }
                        catch (Exception ex)
                        {                                                 
                           
                        }
                    }
                    await Task.Delay(2000);
                }
            });
        }

        public void RunHeartBeat()
        {
            //Task.Run(async () => {
            //    while (true)
            //    {
            //        try
            //        {
            //            var itemmsg = new CommonExtenControl.Model.DeviceModel();
            //            itemmsg.RecvDataTypeModel = CommonPropertyDefin.HeatBeatCmd;
            //            string strMsg = JsonConvert.SerializeObject(itemmsg);
            //            ClientSend(strMsg, 0);
            //        }
            //        catch (Exception ex)
            //        {
                       
            //        }
            //        await Task.Delay(1000);
            //    }
            //});
        }

        private void recv()
        {
            try
            {               
                long fileLength = 0; //接收到数据长度
                while (true)
                {
                    int threadID = Thread.CurrentThread.ManagedThreadId;
                    int firstRcv = 0; //字节长度
                    byte[] buffer = new byte[8 * 1024]; //预先申请8K大小的内存缓存区
                    try
                    {
                        if (socketclient != null) //如果当前的套接字不为空 说明是有连接存在
                        {
                            //获取接受数据的长度，存入内存缓冲区，返回一个字节数组的长度
                            firstRcv = socketclient.Receive(buffer);
                        }

                        try
                        {
                            //判断该数组长度情况
                            if (firstRcv > 0) //说明有数据过来
                            {
                                if (buffer[0] == 0)//0对应文字信息,发消息了
                                {
                                    //将机器接受到的字节数组转换为人可以读懂的字符串   
                                    recStr = Encoding.UTF8.GetString(buffer, 0, firstRcv);
                                    MesgList.Enqueue(recStr);
                                }

                                if (buffer[0] == 1) // 说明发文件过来了，不是消息
                                {
                                    //SQLServer2008R2SP3-KB2979597-x64-CHS.exe
                                    //处理文件名称 去后缀 
                                    string filenameSuffix = recStr.Substring(recStr.LastIndexOf("."));

                                    string RootFloder = AppDomain.CurrentDomain.BaseDirectory + "\\RecvData";
                                    if (!Directory.Exists(RootFloder))
                                    {
                                        Directory.CreateDirectory(RootFloder);
                                    }
                                    string ItemP = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
                                    string SaveDBPath = "RecvData" + "\\" + ItemP;

                                    string ItemFloder = RootFloder + "\\" + ItemP;
                                    if (!Directory.Exists(ItemFloder))
                                    {
                                        Directory.CreateDirectory(ItemFloder);
                                    }
                                    string savePath = ItemFloder + "\\" + recStr;
                                    int rec = 0;
                                    long recFileLength = 0;
                                    bool firstWrite = true;
                                    using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                                    {
                                        while (recFileLength < fileLength)
                                        {
                                            if (firstWrite)
                                            {
                                                fs.Write(buffer, 1, firstRcv - 1);
                                                fs.Flush();
                                                recFileLength += firstRcv - 1;
                                                firstWrite = false;
                                            }
                                            else
                                            {
                                                rec = socketclient.Receive(buffer);
                                                fs.Write(buffer, 0, rec);
                                                fs.Flush();
                                                recFileLength += rec;
                                            }
                                        }
                                        //接收完毕 关闭流
                                        fs.Close();
                                    } //using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                                    string fName = savePath.Substring(savePath.LastIndexOf("\\") + 1);
                                    string fPath = savePath.Substring(0, savePath.LastIndexOf("\\"));
                                    string strMsg = $"{DateTime.Now}====成功接收了文件... 【\" + fName + \"】";
                                   

                                }
                                if (buffer[0] == 2)//2对应文件名字和长度
                                {
                                    string fileNameWithLength = Encoding.UTF8.GetString(buffer, 1, firstRcv - 1);
                                    //截取最后一个"-" 之前的数据
                                    recStr = fileNameWithLength.Substring(0, fileNameWithLength.LastIndexOf('-'));

                                    fileLength = Convert.ToInt64(fileNameWithLength.Split('-').Last());
                                }
                                buffer = null;
                            }////说明有数据过来
                        }
                        catch (Exception ex) 
                        {
                            
                        }
                    }
                    catch (Exception ex)
                    {                        
                        //LogManager.WriteLog(LogTypeEnum.Exception, "recv", ex.Message);
                        //socketServer.Close();//关闭之前accept出来的和客户端进行通信的套接字
                    
                    }



                }
            }
            catch (Exception ex)
            {
               
            }
        }


        public string GetMd5(string password)
        {
            byte[] pasArray = System.Text.Encoding.Default.GetBytes(password);
            pasArray = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(pasArray);
            string rMd5Str = "";
            foreach (byte ibyte in pasArray)
                rMd5Str += ibyte.ToString("x").PadLeft(2, '0');
            return rMd5Str;
        }

        public string GetPcInfo()
        {
            string RStr = "";
            try
            {
                //CPU
                ManagementClass mc = new ManagementClass("Win32_Processor");
                ManagementObjectCollection moc = mc.GetInstances();
                string strID = null;
                foreach (ManagementObject mo in moc)
                {
                    strID = mo.Properties["ProcessorId"].Value.ToString();
                    break;
                }

                //主板
                ManagementClass mc2 = new ManagementClass("Win32_BaseBoard");
                ManagementObjectCollection moc2 = mc2.GetInstances();

                foreach (ManagementObject mo in moc2)
                {
                    strID += mo.Properties["SerialNumber"].Value.ToString();
                    break;
                }

                //硬盘
                ManagementClass mc3 = new ManagementClass("Win32_PhysicalMedia");
                //网上有提到，用Win32_DiskDrive，但是用Win32_DiskDrive获得的硬盘信息中并不包含SerialNumber属性。   
                ManagementObjectCollection moc3 = mc3.GetInstances();
                foreach (ManagementObject mo in moc3)
                {
                    strID += mo.Properties["SerialNumber"].Value.ToString();
                    break;
                }
                //BIOS
                ManagementClass mc4 = new ManagementClass("Win32_BIOS");
                ManagementObjectCollection moc4 = mc.GetInstances();
                foreach (ManagementObject mo in moc4)
                {
                    strID += mo.Properties["SerialNumber"].Value.ToString();
                    break;
                }

                RStr = GetMd5(strID);
            }
            catch (Exception ex) 
            {
               
            }
            return RStr;
        }

        public void ClientSend(string SendStr, byte symbol)
        {
            try
            {
                if (socketclient == null)
                {      
                    return;
                }

                if (!socketclient.Connected) 
                {
                    return;
                }

                byte[] buffer = Encoding.UTF8.GetBytes(SendStr);

                byte[] newBuffer = new byte[buffer.Length + 1];

                newBuffer[0] = symbol;

                Buffer.BlockCopy(buffer, 0, newBuffer, 1, buffer.Length);
                socketclient.Send(newBuffer);
            }
            catch (Exception ex) 
            {
               
            }

        }

        public void ToSendFile()
        {
            OpenFileDialog openFileDlg = new OpenFileDialog();
            if (openFileDlg.ShowDialog() == true)
            {
                filePath = openFileDlg.FileName;
                fileName = openFileDlg.SafeFileName;
                worker.WorkerReportsProgress = true;
                worker.RunWorkerAsync();               
            }
         
        }

        private void SendFile(string fileFullPath)
        {
            long fileLength = new FileInfo(fileFullPath).Length;
            string totalMsg = string.Format("{0}-{1}", fileName, fileLength);
            ClientSend(totalMsg, 2);
            byte[] buffer = new byte[2 * 1024];
            using (FileStream fs = new FileStream(fileFullPath, FileMode.Open, FileAccess.Read))
            {
                int readLength = 0;
                bool firstRead = true;
                long sentFileLength = 0;
                while ((readLength = fs.Read(buffer, 0, buffer.Length)) > 0 && sentFileLength < fileLength)
                {
                    sentFileLength += readLength;
                    worker.ReportProgress(ProcessBarValue(sentFileLength, fileLength));
                    if (firstRead)
                    {
                        byte[] firstBuffer = new byte[readLength + 1];
                        firstBuffer[0] = 1;
                        Buffer.BlockCopy(buffer, 0, firstBuffer, 1, readLength);
                        socketclient.Send(firstBuffer, 0, readLength + 1, SocketFlags.None);
                        firstRead = false;
                    }
                    else
                    {
                        socketclient.Send(buffer, 0, readLength, SocketFlags.None);
                    }
                }
                fs.Close();
            }
            Console.WriteLine("发送完成");
        }
        private int ProcessBarValue(long iSumCount, long iFileLength)
        {
            double value = ((double)iSumCount) / ((double)iFileLength);
            string str1 = String.Format("{0:F}", value);//默认为保留两位
            int value2 = (int)(Math.Round(decimal.Parse(str1), 2) * 100);
            //判断数字落在哪个区域
            return value2;//ValueParse(value2,0);
        }

        private void RunRecveMsg()
        {
            //Task.Run(async () => {
            //    while (true)
            //    {
            //        try
            //        {
            //            if (MesgList.Count > 0)
            //            {
            //                string strMsg = "";
            //                bool flg = MesgList.TryDequeue(out strMsg);
            //                if (flg)
            //                {
            //                    JObject jsonObj = JObject.Parse(strMsg);
            //                    List<JToken> listJToken = jsonObj.Root.ToList();
            //                    foreach (var item in listJToken)
            //                    {
            //                        var temp_item = (JProperty)item;
            //                        if (temp_item.Name == "RecvDataTypeModel")
            //                        {
            //                            if (!string.IsNullOrEmpty(temp_item.Value.ToString()))
            //                            {
            //                                if (temp_item.Value.ToString() == CommonPropertyDefin.FileDateCmd)
            //                                {
            //                                    var itemModel = JsonConvert.DeserializeObject<CommonExtenControl.Model.FileModel>(strMsg);
            //                                }
            //                                else if (temp_item.Value.ToString() == CommonPropertyDefin.BackLoadDateCommand)
            //                                {
            //                                    Event.GetEvent<ReloadDateEvent>().Publish(true);
            //                                }
            //                                else if (temp_item.Value.ToString() == CommonPropertyDefin.BackMsgCommand)
            //                                {
            //                                    string MsgTip = "";
            //                                    var itemModel = JsonConvert.DeserializeObject<CommonExtenControl.Model.DeviceModel>(strMsg);
            //                                    if (itemModel.CurrentOperationResultTypee == OperationResultType.Success)
            //                                    {
            //                                        MsgTip = "操作成功";
            //                                    }
            //                                    else
            //                                    {
            //                                        MsgTip = "操作失败";
            //                                    }
            //                                    MessageControl.Warning(MsgTip, "RootMessageTooken");
            //                                }
            //                            }
            //                        }
            //                    }


            //                }
            //            }
            //        }
            //        catch (Exception ex)
            //        {
                        
            //        }


            //        await Task.Delay(50);
            //    }
            //});
        }
        private void SaveDataConfig()
        {
            try
            {
                string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "..", "Roaming"); // 获取 AppData\Roaming 路径

                if (!Directory.Exists(filePath))
                    Directory.CreateDirectory(filePath); // 创建 AppData\Roaming 目录（若不存在）

                string fileName = "ManagerConfig.data"; // 要保存的文件名
                string content = ""; // 文件内容
                File.WriteAllText(Path.Combine(filePath, fileName), content); // 写入文件
            }
            catch (Exception ex) 
            {
            
            }
        }
        private void KillTerminalMirroringProcess()
        {
            try
            {
                Process[] items = Process.GetProcesses();
                var targetP = items.Where(item => item.ProcessName == "TerminalMirroring" || item.ProcessName == "TerminalMirroring.exe").FirstOrDefault();
                if (targetP != null)
                {
                    targetP.Kill();
                }
            }
            catch (Exception ex)
            {
                
            }
        }
        private void KillAiVideoDiagnoseProcess()
        {
            try
            {
                Process[] items = Process.GetProcesses();
                var targetP = items.Where(item => item.ProcessName == "AiVideoDiagnose" || item.ProcessName == "AiVideoDiagnose.exe").FirstOrDefault();
                if (targetP != null)
                {
                    targetP.Kill();
                }
            }
            catch (Exception ex)
            {
                
            }
        }

    }
}
